<!-- components/SubscribeMessage.vue -->
<template>
  <!-- 订阅消息组件容器 -->
  <view class="subscribe-message-component">
    <!-- 集成订阅的按钮 -->
    <button 
      v-if="showSubscribeButton"
      class="subscribe-btn"
      :class="[customClass]"
      open-type="subscribeMessage"
      @click="handleSubscribeClick"
      :subscribe-message-template-id-list="templateIdList"
      :subscribe-message-scene="scene"
      :disabled="isLoading || disabled"
      :loading="isLoading"
    >
      <slot name="button-content">
        {{ buttonText }}
      </slot>
    </button>
    
    <!-- 授权状态提示 -->
    <view v-if="showStatusTip && authStatus" class="auth-status-tip">
      <text :class="['status-text', authStatus.type]">
        {{ authStatus.message }}
      </text>
    </view>
    
    <!-- 重新授权提示 -->
    <view v-if="showReAuthTip" class="reauth-tip">
      <text class="tip-text">订阅消息授权已过期或拒绝，请重新授权</text>
      <text class="reauth-action" @click="triggerReAuth">立即授权</text>
    </view>
  </view>
</template>

<script setup>
import { ref, computed, onMounted, watch } from 'vue'

// 组件属性定义
const props = defineProps({
  // 模板ID列表
  templateIds: {
    type: Array,
    default: () => ['8BYCmgqMs93PA1OxJao3t5VxI-6XxBiR_jKuUVHqIWQ'] // 默认模板ID[6](@ref)
  },
  // 使用场景
  scene: {
    type: String,
    default: 'enterPage'
  },
  // 是否显示订阅按钮
  showButton: {
    type: Boolean,
    default: true
  },
  // 按钮自定义类名
  customClass: {
    type: String,
    default: ''
  },
  // 按钮文本
  buttonText: {
    type: String,
    default: '订阅消息'
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false
  },
  // 是否显示状态提示
  showStatusTip: {
    type: Boolean,
    default: true
  },
  // 自动检查订阅状态
  autoCheckStatus: {
    type: Boolean,
    default: true
  },
  // 需要强制订阅（拒绝时阻止操作）
  forceSubscribe: {
    type: Boolean,
    default: false
  }
})

// 事件定义
const emit = defineEmits([
  'subscribe-success', // 订阅成功
  'subscribe-fail',    // 订阅失败
  'subscribe-reject',  // 用户拒绝
  'status-change',     // 订阅状态变化
  'click'             // 按钮点击
])

// 响应式数据
const templateIdList = ref([...props.templateIds])
const isLoading = ref(false)
const hasSubscribed = ref(false)
const showSubscribeButton = ref(props.showButton)
const showReAuthTip = ref(false)
const authStatus = ref(null)
const subscriptionSetting = ref(null)

// 计算属性
const subscriptionStatus = computed(() => {
  return {
    subscribed: hasSubscribed.value,
    setting: subscriptionSetting.value,
    canSubscribe: showSubscribeButton.value
  }
})

// 生命周期
onMounted(() => {
  if (props.autoCheckStatus) {
    checkSubscriptionStatus()
  }
})

// 监听模板ID变化
watch(() => props.templateIds, (newIds) => {
  templateIdList.value = [...newIds]
}, { deep: true })

/**
 * 检查用户订阅消息状态[2](@ref)
 */
const checkSubscriptionStatus = () => {
  if (!uni.getSetting) return
  
  uni.getSetting({
    withSubscriptions: true,
    success: (res) => {
      console.log('订阅消息设置:', res.subscriptionsSetting)
      subscriptionSetting.value = res.subscriptionsSetting
      
      if (res.subscriptionsSetting && templateIdList.value.length > 0) {
        const mainTemplateId = templateIdList.value[0]
        const itemSetting = res.subscriptionsSetting.itemSettings || {}
        hasSubscribed.value = itemSetting[mainTemplateId] === 'accept'
        
        showReAuthTip.value = itemSetting[mainTemplateId] === 'reject'
        showSubscribeButton.value = itemSetting[mainTemplateId] !== 'accept'
      }
      
      emit('status-change', subscriptionStatus.value)
    },
    fail: (err) => {
      console.error('获取订阅设置失败:', err)
    }
  })
}

/**
 * 处理订阅按钮点击
 */
const handleSubscribeClick = async () => {
  emit('click')
  
  if (isLoading.value) return
  
  try {
    isLoading.value = true
    authStatus.value = null
    
    const result = await requestSubscribeMessage()
    
    if (result) {
      await handleSubscribeSuccess(result)
    } else {
      await handleSubscribeReject()
    }
    
  } catch (error) {
    await handleSubscribeError(error)
  } finally {
    isLoading.value = false
  }
}

/**
 * 请求订阅消息授权[6](@ref)
 */
const requestSubscribeMessage = () => {
  return new Promise((resolve, reject) => {
    if (!uni.requestSubscribeMessage) {
      uni.showModal({
        title: '提示',
        content: '当前微信版本过低，请升级后使用',
        showCancel: false
      })
      reject(new Error('API not supported'))
      return
    }
    
    uni.requestSubscribeMessage({
      tmplIds: templateIdList.value,
      success: (res) => {
        console.log('订阅消息授权结果:', res)
        resolve(res)
      },
      fail: (err) => {
        reject(err)
      }
    })
  })
}

/**
 * 处理订阅成功
 */
const handleSubscribeSuccess = (result) => {
  // 检查所有模板的授权状态[5](@ref)
  const allAccepted = templateIdList.value.every(tmplId => 
    result[tmplId] === 'accept'
  )
  
  if (allAccepted) {
    hasSubscribed.value = true
    showSubscribeButton.value = false
    showReAuthTip.value = false
    
    authStatus.value = {
      type: 'success',
      message: '订阅消息成功'
    }
    
    emit('subscribe-success', result)
    
    uni.showToast({
      title: '订阅成功',
      icon: 'success',
      duration: 2000
    })
    
    return true
  } else {
    handleSubscribeReject(result)
    return false
  }
}

/**
 * 处理订阅拒绝
 */
const handleSubscribeReject = (result = {}) => {
  const rejectedTemplates = templateIdList.value.filter(tmplId => 
    result[tmplId] === 'reject'
  )
  
  hasSubscribed.value = false
  showReAuthTip.value = true
  
  authStatus.value = {
    type: 'error',
    message: '订阅消息被拒绝'
  }
  
  emit('subscribe-reject', {
    rejectedTemplates,
    fullResult: result
  })
  
  // 如果需要强制订阅，显示重新授权弹窗
  if (props.forceSubscribe) {
    showReAuthModal()
  }
  
  return false
}

/**
 * 处理订阅错误[2](@ref)
 */
const handleSubscribeError = (error) => {
  console.error('订阅消息错误:', error)
  
  let errorMessage = '订阅失败，请重试'
  
  // 处理特定错误码
  if (error.errCode === 20004) {
    errorMessage = '订阅消息功能被关闭'
    showReAuthTip.value = true
    showReAuthModal()
  }
  
  authStatus.value = {
    type: 'error',
    message: errorMessage
  }
  
  emit('subscribe-fail', error)
  
  if (!props.forceSubscribe) {
    uni.showToast({
      title: errorMessage,
      icon: 'none'
    })
  }
  
  return false
}

/**
 * 显示重新授权弹窗
 */
const showReAuthModal = () => {
  uni.showModal({
    title: '订阅提示',
    content: '需要订阅消息才能正常使用服务，是否重新授权？',
    confirmText: '重新授权',
    cancelText: props.forceSubscribe ? '退出' : '取消',
    success: (res) => {
      if (res.confirm) {
        triggerReAuth()
      } else if (props.forceSubscribe) {
        // 强制订阅模式下，用户拒绝则退出小程序
        uni.navigateBack({ delta: 10 })
      }
    }
  })
}

/**
 * 触发重新授权
 */
const triggerReAuth = () => {
  showReAuthTip.value = false
  setTimeout(() => {
    handleSubscribeClick()
  }, 300)
}

/**
 * 手动触发订阅（供父组件调用）
 */
const triggerSubscribe = async () => {
  return await handleSubscribeClick()
}

/**
 * 重置订阅状态
 */
const resetSubscribeStatus = () => {
  hasSubscribed.value = false
  showSubscribeButton.value = true
  showReAuthTip.value = false
  authStatus.value = null
}

// 暴露方法给父组件
defineExpose({
  triggerSubscribe,
  checkSubscriptionStatus,
  resetSubscribeStatus,
  subscriptionStatus
})
</script>

<style scoped>
.subscribe-message-component {
  width: 100%;
}

.subscribe-btn {
  width: 100%;
  height: 96rpx;
  line-height: 96rpx;
  background: #3264ed;
  color: #fff;
  border-radius: 20rpx;
  font-size: 32rpx;
  border: none;
}

.subscribe-btn:after {
  border: none;
}

.subscribe-btn[disabled] {
  background: #cccccc;
  color: #666666;
}

.auth-status-tip {
  margin-top: 20rpx;
  padding: 20rpx;
  border-radius: 12rpx;
  text-align: center;
}

.status-text {
  font-size: 26rpx;
}

.status-text.success {
  color: #07C160;
  background: #f0f9f4;
}

.status-text.error {
  color: #e64340;
  background: #fef0f0;
}

.status-text.warning {
  color: #f90;
  background: #fff9e6;
}

.reauth-tip {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 20rpx;
  padding: 20rpx;
  background: #fff9e6;
  border-radius: 12rpx;
  font-size: 24rpx;
}

.tip-text {
  color: #f90;
  margin-right: 20rpx;
}

.reauth-action {
  color: #3264ed;
  text-decoration: underline;
}
</style>